window.onload=function()
{
   hu=$(".u")
   hu.html("<p>56</p>")
   hu.attr("id","op")
   console.log(hu.getHtml())
   // //第二级选择是在第一级的基础上进行选择，如果第二级跑出了
   // // 第一级，那么是 选择 不到的。
   // lp=hu.selector("#cls")
   // //css第一个是属性，第二个是值，第三个是可以指定也可以不指定。
   // //可以是单个数，也可以是一个包含下标的数组
   // console.log(lp.css("color","red",[0,1,2]))
}

class jq
{
   //parentContainer有可能为字符空
   //可能为html对象，可能为数组对象
   // 两个类型都为object，但是一个有length
   //一个没有。
   parentContainer=""
   //这里进行样式设置
   css(css,value,index="all")
   {
      //如果是对所有的被选元素进行添加颜色且被选元素容器中不为空
      // 就进行样式设置，但是又可能被选有可能是很多个，也有可能是一个
      if(index=="all"&&this.parentContainer.length!=0)
      {
         // 如果被选元素时一个，这里就不起作用，容器没有length属性
         // 如果有很多个，那么就在这里修改。
         for(var i=0;i<this.parentContainer.length;i++)
         {
            this.parentContainer[i].style[css]=value
         }
         //如果被选元素时一个，这里就不起作用，容器没有length属性
         // 那么就在这里改。
         if(this.parentContainer.length==undefined)
         {
            this.parentContainer.style[css]=value
         }
      }
      // 这里如果被选元素有很多，且指定其中某个进行修改
      else
      {
         //如果index传入的是数组，那么长度不为undefind
         // 如果是数字，那么就是undefind
         if(index.length!=undefined)
         {
            for(var i=0;i<index.length;i++)
            {
               if(this.parentContainer.length<index[i])
               {
                  console.log("数组中第("+i+"个下标"+index[i]+")：有问题")
                  break;
               }
               this.parentContainer[index[i]].style[css]=value
            }
         }
         //传入的index如果是数字那么就不为undefind
         else
         {
            if(this.parentContainer.length<index)
            {
               console.log("数组中第0个下标:"+index+"有问题")
            }
            this.parentContainer[index].style[css]=value
         }
      }
   }
   //这里设置html
   html(html)
   {
      var obj=this.parentContainer
      if(obj[0]!=null)
      {
         for(var i=0;i<obj.length;i++)
         {
            obj[i].innerHTML=html
         }
      }
   }
   // 这里设置纯文本
   text(text)
   {
      var obj=this.parentContainer
      if(obj[0]!=null)
      {
         for(var i=0;i<obj.length;i++)
         {
            obj[i].innerText=text
         }
      }
   }
   //设置属性
   attr(attr,value)
   {
      var obj=this.parentContainer
      if(obj[0]!=null)
      {
         for(var i=0;i<obj.length;i++)
         {
            obj[i].setAttribute(attr,value)
         }
      }
   }
   // 获取属性
   getAttr(attr)
   {
      var obj=this.parentContainer
      var attrList=[]
      if(obj[0]!=null)
      {
         for(var i=0;i<obj.length;i++)
         {
            attrList.push(obj[i].getAttribute(attr))
         }
      }
      return attrList
   }
   // 获取html
   getHtml()
   {
      var obj=this.parentContainer
      var htmlList=[]
      if(obj[0]!=null)
      {
         for(var i=0;i<obj.length;i++)
         {
            htmlList.push(obj[i].innerHTML)
         }
      }
      return htmlList
   }
   // 获取纯文本
   getText()
   {
      var obj=this.parentContainer
      var textList=[]
      if(obj[0]!=null)
      {
         for(var i=0;i<obj.length;i++)
         {
            textList.push(obj[i].innerText)
         }
      }
      return textList
   }
   // 这里进行选择
   selector(obj)
   {
      // 创建一个新的对象好返回出去，一边再调取类中的方法
      var newObj=new jq()
      // 这里是临时元素的容器
      var clsElement=""
      var idElement=""
      var tagElement=""
      var single
      //如果传入的选择对象不为空、 不为数字才进行选择。
      if(obj.length!=0&&obj.length!=undefined)
      {
         // 如果被要选择的是类***************
         if(obj.indexOf(".")!=-1)
         {
            // 如果容器中是元素数组那么它的长度不为0和未定义。
            // 如果是当个元素那么！=0满足，但是undefined不满足
            // 如果为空，那么！=0不满足。所以。这里是限制容器为数组
            if(this.parentContainer.length!=0 &&this.parentContainer.length!=undefined)
            {
               // 这里是临时变量，好收集所有父元素的子元素，这样把子元素展开了，不再是树型
               // 结构
               var tempLi=[]
               //通过循环容器获取上一级父元素。
               for(var i=0;i<this.parentContainer.length;i++)
               {
                  // 获取每个父元素的子元素u
                  clsElement=this.parentContainer[i].children
                  for(var j=0;j<clsElement.length;j++)
                  {
                     // 如果是我要找的那个对象那么就放在临时容器中
                     if(clsElement[j].className==obj.replace(".",""))
                     {
                        tempLi.push(clsElement[j])
                     }
                  }
               }
               // 在把临时容器放入元素容器中（整个jq对象）
               this.parentContainer=tempLi
            }
            //如果元素容器为数组，那么就进入上面
            // 接下来就是要么为空，要么为单个元素就进入这里。
            else
            {
               // 如果容器为空就进入这里
               if(this.parentContainer.length==0)
               {
                  clsElement=document.getElementsByClassName(obj.replace(".",""))
               }
               // 如果为单个元素就进入这里,获取子元素
               else
               {
                  clsElement=this.parentContainer.children
               }
               //设置元素容器数组，这样好直接设置元素容器
               this.parentContainer=[]
               for(var i=0;i<clsElement.length;i++)
               {
                  //一个一个判断他的类是不是我指定的类是就放入元素容器中。
                  single=clsElement[i]
                  if(single.className==obj.replace(".",""))
                  {
                     this.parentContainer.push(single)
                  }
               }
            }
         }
         // 如果通过id选中就进入这里*****************
         else if (obj.indexOf("#")!=-1)
         {
            //如果元素容器为数组，说明这里是二次选择。
            if(this.parentContainer.length!=0&&this.parentContainer.length!=undefined)
            {
               var  tempLi=[]
               // 通过循环获取每个父元素
               for(var j=0;j<this.parentContainer.length;j++)
               {
                  idElement=this.parentContainer[j].children
                  // 通过循环获取每个父元素的每个子元素。
                  for(var i=0;i<idElement.length;i++)
                  {
                     single=idElement[i]
                     // 如果是我要找的子元素，那么就放在元素容器中
                     // 由于是通过id选择，所以整个页面中只能有独一无二的
                     // id所以只能有一次。
                     if(single.id==obj.replace("#",""))
                     {
                        tempLi.push(single)
                     }
                  }
               }
               // 如果找到多个相同id的元素，说明文本中id取名重复
               // 那么就进行提示。
               if(tempLi.length>1)
               {
                  console.log("页面中有多个相同id："+obj.replace("#",""))
               }
               else if(tempLi.length==1)
               {
                  this.parentContainer=tempLi
               }
               else
               {
                  //如果为空说明没有找到
                  console.log("没有此id："+obj.replace("#",""))
               }
            }
            //如果元素容器为空或者是是当个元素就 进入这里
            else
            {
               //如果元素容器为空 那么就是第一次选择
               if(this.parentContainer.length==0)
               {
                  this.parentContainer=[document.getElementById(obj.replace("#",""))]
               }
               //如果元素容器为单个元素就进入这里
               // 这里要使用elseif,由于上一层使用
               // this.parentContainer=document.getElementById(obj.replace(".",""))
               // 修改了 parentCOntainer
               else if(this.parentContainer.length==undefined)
               {
                  // 临时容器，用来就收子元素，好展开树型结构
                  var tempLi=[]
                  idElement=this.parentContainer.children
                  //通过循环获取父元素中子元素，通过比对找到自己想要的元素
                  for(var i=0;i<idElement.length;i++)
                  {
                     single=idElement[i]
                     // 通过比对找到自己想要的元素
                     if(single.id==obj.replace("#",""))
                     {
                        tempLi.push(single)
                     }
                  }
                  //由于是id找如果多了说明页面中有相同的id名
                  if(tempLi.length>1)
                  {
                     console.log("页面中有多个相同id："+obj.replace("#",""))
                  }
                  //如果只有一个那么 就放在元素容器中
                  else if(tempLi.length==1)
                  {
                     this.parentContainer=tempLi
                  }
                  else
                  {
                     //如果为空说明没有找到
                     console.log("没有此id："+obj.replace("#",""))
                  }
               }
            }
         }
         //如果不是通过类、id找那么就是元素标签找*******************。
         else
         {
            // 如果元素容器为元素数组
            if(this.parentContainer.length!=undefined&&this.parentContainer.length!=0)
            {
               // 设置临时容器好接收父元素的子元素。展开树型结构
               var tempLi=[]
               // 通过循环找到元素容器中的元素
               for(var i=0;i<this.parentContainer.length;i++)
               {
                  //通过循环找到每个父元素的每个子元素。
                  tagElement=this.parentContainer[i].children
                  for(var j=0;j<tagElement.length;j++)
                  {
                     // 如果子元素是我要找的元素就放入。
                     if(tagElement[j].nodeName==obj.toUpperCase())
                     {
                        tempLi.push(tagElement[j])
                     }
                  }
               }
               if(tempLi.length==0)
               {
                  console.log("没有或者此元素标签错误："+obj)
               }
               this.parentContainer=tempLi
            }
            //如果元素容器为空（第一次选择），或者当个元素就进入这里
            else
            {
               var tempLi=[]
               // 如果元素容器是空，是第一次选择
               if(this.parentContainer.length==0)
               {
                  this.parentContainer=document.getElementsByTagName(obj)
               }
               //如果元素容器是单个元素
               //由于上一层使用了this.parentContainer=document.getElementsByTagName(obj)
               else if(this.parentContainer.length==undefined)
               {
                  tagElement=this.parentContainer.children
                  console.log(tagElement)
                  for(var i=0;i<tagElement.length;i++)
                  {
                     console.log(tagElement[i])
                     if(tagElement[i].nodeName==obj.toUpperCase())
                     {
                        tempLi.push(tagElement[i])
                     }
                  }
                  this.parentContainer=tempLi
               }
            }
         }
      }
      //如果二级查询时发现元素容器为空，那么就警告，并不返回新对象
      if(this.parentContainer.length==0)
      {
         console.log("输入的元素有问题:"+obj)
         return this
      }
      //这里设置返回对象的元素容器，一边二级查询使用
      newObj.parentContainer=this.parentContainer
      return this
   }
   //解析并赋值
   setCss(css,obj)
   {
      var spD=""
      var spM=""
      var cssDic={}
      for(var key in css)
      {
         if(css[key].includes(";"))
         {
            spD=css[key].split(";")
            for(var i=0;i<spD.length;i++)
            {
               if(spD[i].includes(":"))
               {
                  console.log(spD[i])
                  spM=spD[i].split(":")
                  if(spM[1].includes("+"))
                  {
                     obj[key][spM[0]]=obj[key][spM[0]]+" "+spM[1].replace("+","")
                     cssDic[key]=
                     {
                        [spM[0]]:obj[key][spM[0]]+" "+spM[1].replace("+","")
                     }
                  }
                  else if(spM[1].includes("--"))
                  {
                     obj[key][spM[0]]=obj[key][spM[0]].replace(spM[1].replace("--",""),"")
                     cssDic[key]=
                     {
                        [spM[0]]:obj[key][spM[0]].replace(spM[1].replace("--",""),"")
                     }
                  }
                  else
                  {
                     obj[key][spM[0]]=spM[1]
                     if(!Object.keys(cssDic).includes(key))
                     {
                        cssDic[key]=
                        {
                           [spM[0]]:spM[1]
                        }
                     }
                     else
                     {
                        cssDic[key][spM[0]]=spM[1]
                     }
                  }
               }
            }
         }
         else
         {
            if(css[key].includes(":"))
            {
               spM=css[key].split(":")
               if(spM[1].includes("+"))
               {
                  obj[key][spM[0]]=obj[key][spM[0]]+" "+spM[1].replace("+","")
                  cssDic[key]=
                  {
                     [spM[0]]:obj[key][spM[0]]+" "+spM[1].replace("+","")
                  }
               }
               else if(spM[1].includes("--"))
               {
                  obj[key][spM[0]]=obj[key][spM[0]].replace(spM[1].replace("--",""),"")
                  cssDic[key]=
                  {
                     [spM[0]]:obj[key][spM[0]].replace(spM[1].replace("--",""),"")
                  }
               }
               else
               {
                  obj[key][spM[0]]=spM[1]
                  cssDic[key]=
                  {
                     [spM[0]]:spM[1]
                  }
               }
            }
            else
            {
               obj[key]=css[key]
               cssDic[key]=css[key]
            }
         }
      }
      return cssDic
   }
   /*************以下是拖选函数**************/
   // 由于开始是在纯文本中开始的所以一定没有子元素。
   startToNext(obk,css={},textArea="text")
   {
      var te=document.getElementById(textArea)
      var clone=obk.cloneContents()
      var chL=clone.childNodes
      var addFlag=0
      var span=document.createElement("span")
      var children=""
      var temp=document.createElement("span")
      var spD=""
      var spM=""
      var child=chL
      span.appendChild(clone)
      // return
      // 因为appendChild()会抽取cloneContents()内容，所以使用for会导致长度变化
      // 同时for中也是放在其他容器中来获取自己源码。这里直接把所有内容
      // 放在了自己容器里面，再直接放入就行了就不用活动自己的源码
      var tdFlag=0
      if(child!=null&&child.length!=0&&child[0]!=undefined)
      {
         var tbFlag=[]
         for(var i=0;i<child.length;i++)
         {
            if(child[i].tagName=="TD")
            {
               tdFlag=1
               var parent=obk.commonAncestorContainer
               var td=parent.getElementsByClassName(child[i].className)[0]
               self.etCss(css,td)
            }
         }
         if(tdFlag==1)
         {
            if(te!=null&&te!=undefined&&te.length!=0&&te.childNodes[te.childNodes.length-1].innerHTML!="<br>")
            { 
               te.innerHTML+="<br>"
            }
            return
         }
      }
      
      span.appendChild(clone)
      // var s=document.createElement("span")
      // s.appendChild(obk.startContainer)
      // console.log(span.innerText,s.innerText)
      // return
      //如果选择的是容器中所有内容且不是编辑区域则直接在父容器中修改
      if(obk.startContainer.parentNode.childNodes.length==1&&obk.startContainer.parentNode!=te&&obk.startContainer.nodeValue==obk.endContainer.nodeValue&&span.innerText==obk.startContainer.nodeValue)
      {
         span=obk.startContainer.parentNode
         var newCss=this.setCss(css,span)
         for(key in newCss)
         {
            if(typeof newCss[key]=== "object" && newCss[key]!==null && newCss[key].constructor== Object)
            {
               for(var key2 in newCss)
               {
                  this.changeChild(span,key,key2,newCss[key][key2])
               }
            }
            else
            {
               this.changeChild(span,key,newCss[key])
            }
         }

         if(te!=null&&te!=undefined&&te.length!=0&&te.childNodes[te.childNodes.length-1].innerHTML!="<br>")
         { 
            te.innerHTML+="<br>"
         }
         return
      }
      //如果不是纯文本就在添加包装
      else
      {
         //通过新建的span父容器继承原来的父容器属性来解决
         //背景颜色和字体大小不匹配的问题。
         var at={}
         if((obk.commonAncestorContainer instanceof Text)  && obk.commonAncestorContainer.parentNode!=te)
         {
            at=obk.commonAncestorContainer.parentNode.attributes
         }
         else if((obk.commonAncestorContainer instanceof Text)  && obk.commonAncestorContainer.parentNode==te)
         {
            at={}
         }
         else if(!(obk.commonAncestorContainer instanceof Text)  && obk.commonAncestorContainer.parentNode!=te)
         {
            at=obk.commonAncestorContainer.attributes
         }
         for(var p=0;p<at.length;p++)
         {
            span[at[p].name]=at[p].value
            this.changeChild(span,at[p].name,at[p].value)
         }
         var newCss=this.setCss(css,span)
         for(var key in newCss)
         {
            if(typeof newCss[key]== "object" && newCss[key]!==null && newCss[key].constructor== Object)
            {
               for(var key2 in newCss[key])
               {
                  this.changeChild(span,key,key2,newCss[key][key2])
               }
            }
            else
            {
               this.changeChild(span,key,newCss[key])
            }
         }
         obk.deleteContents()
         obk.insertNode(span)
      }
      if(te!=null&&te!=undefined&&te.length!=0&&te.childNodes[te.childNodes.length-1].innerHTML!="<br>")
       { 
          te.innerHTML+="<br>"
       }
   }
   //把所有子元素添加样式
   changeChild(p,key,name,value=0)
   {
      var cd=p.childNodes
      for (var i=0;i<cd.length;i++)
      {
         if(!(cd[i] instanceof Text))
         {
            if(value!=0)
            {
               cd[i][key][name]=value
               this.changeChild(cd[i],key,name,value)
            }
            else
            {
               cd[i][key]=name
               this.changeChild(cd[i],key,name)
            }
         }
      }
   }
   //******入口函数：使用方法如要设置文字颜色："sytle=color:red;backgroun:blue"
   // 每次只能设置一次属性如style或则id
   selsectObj(css,textArea="text")
   {
      var getSelection=document.getSelection()
      var rangeCount=getSelection.rangeCount
      // alert(getSelection.getRangeAt(0))
      for(var i=0;i<rangeCount;i++)
      {
         var getRange=getSelection.getRangeAt(i)
         this.startToNext(getRange,css,textArea)
         //还是要取消选中否则添加span容器后开始容器发生了变化
         //导致出现一些问题。
         this.closeSelection()
      }
   }
   closeSelection()
   {
      var body = document.getElementsByTagName('body')[0];
      document.getSelection().collapse(body,0);
   }
   /******以上是托选行数*************/
}

//使用$符号设置的函数模范jqury
function $(obj)
{
   newObj=new jq()
   if(obj==undefined||obj==null||obj.length==0)
   {
      return newObj
   }
   else
   {
      return newObj.selector(obj)
   }
}

